package com.xtxbyj;

import java.io.*;
import java.net.URLDecoder;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Hello world!
 *
 */
public class App
{
    private static String type_picture="";
    private static String type_video="";

    private static String path_picture=null;
    private static String path_video=null;
    private static String warnFiles=null;
    private static String repeatFiles=null;
    private static String rootPath=null;
    private static boolean isWidows=false;
    private static boolean deleteFile=true;

    static {
        File file= null;
        try {
            file = new File(URLDecoder.decode(new App().getClass().getProtectionDomain().getCodeSource().getLocation().getFile(),"utf-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            System.exit(1);
        }
        rootPath=file.getParent();
//        rootPath="/data/home/xtxb-di/datadisk/data/private/相片整理";
        String osName=System.getProperty("os.name").trim();
        isWidows=osName.toLowerCase().indexOf("windows")>=0;
        System.out.println("当前平台: "+osName);

        if("false".equals(System.getProperty("deleteFile"))){
            deleteFile=false;
        }
    }
    public static void main( String[] args )
    {
        String targetRootPath=rootPath+File.separator+new SimpleDateFormat("yyyy-MM-dd整理结果").format(new Date());
        path_picture=targetRootPath+File.separator+"picture";
        path_video=targetRootPath+File.separator+"video";
        warnFiles=targetRootPath+File.separator+"可疑文件";
        repeatFiles=targetRootPath+File.separator+"重复文件";

        /** 获取需要从手机中读取文件的目录*/
        System.out.println("1. 加载图片和视频文件目录设置");
        Properties pro=getFileDirs();
        if(pro==null)
            System.exit(1);

        /** 获取常用的图片和视频文件类型*/
        System.out.println("2. 加载图片和视频文件类型设置");
        getFileType();

        /** 建立到手机存储目录的连接*/
        System.out.println("3. 设置手机存储MTP|SMB目录");
        String mtpRootPath=getMTPRootPath();
        if(mtpRootPath==null)
            System.exit(1);

        /** 读取手机中的图片和视频*/
        System.out.println("4. 下载图片和视频文件");
        readFile(pro,mtpRootPath);
    }

    private static void readFile(Properties pro, String mtpRootPath) {
        pro.forEach((key,value)->{
            if(key.toString().startsWith("dir")){
                System.out.println("---目录:"+mtpRootPath+value);
                File file=new File(mtpRootPath+value);
                if(!file.exists()){
                    return;
                }
                File[] subs=file.listFiles();
                if(subs==null)
                    return;
                System.out.print("-----文件开始下载");
                Map<String,Integer> report=new HashMap<>();
                Map<String,String> warnMap=new HashMap<>();
                Map<String,String> repeatMap=new HashMap<>();
                List<String> nulltMap=new ArrayList<>();
                int total=0;
                int sucNum=0;
                for(File sub: subs){
                    if(sub.getName().contains(".") && !sub.getName().startsWith(".")) {
                        String target=null;
                        String strType=sub.getName().split("\\.")[1];
                        int type = getType(strType);
                        if(type==0){
                            continue;
                        }

                        if(sub.getName().indexOf("_edit_")>0){
                            target=warnFiles;
                            warnMap.put(sub.getName(),target+File.separator+sub.getName());
                        }else {
                            target = getTargetPath(type, sub);
                        }
                        if(target==null){
                            nulltMap.add(sub.getName());
                        }else{
                            total++;
                            if (copyFile(sub, new File(target + File.separator + sub.getName()),repeatMap)) {
                                if(deleteFile) {
                                    sub.delete();
                                }
                                count(report, strType);
                                sucNum++;
                                System.out.print(".");
                            }
                        }
                    }
                }
                System.out.print("\n");
                System.out.println("-----下载文件总数: "+total+" ,成功数量: "+sucNum+" "+report.toString().replace("{","[").replace("}","]"));
                if(!warnMap.isEmpty()) {
                    System.out.println("-----可疑的文件(编辑的临时文件)情况：");
                    warnMap.entrySet().forEach(entry -> System.out.println("-----" + entry.getKey() + "  >>>>  " + entry.getValue()));
                }
                if(!repeatMap.isEmpty()) {
                    System.out.println("-----重复的文件情况：");
                    repeatMap.entrySet().forEach(entry -> System.out.println("-----" + entry.getKey() + "  >>>>  " + entry.getValue()));
                }
                if(!nulltMap.isEmpty()) {
                    System.out.println("----无法判断日期的文件情况：");
                    nulltMap.forEach(str -> System.out.println("-----" + str));
                }
            }
        });
    }

    private static Properties getFileDirs(){
        File file= new File(rootPath+File.separator+ "dir.conf");
        Properties pro=new Properties();
        if(file.exists()) {
            try (FileReader fr = new FileReader(file)) {
                pro.load(fr);
                pro.keySet().forEach(key->{
                    pro.put(key,pro.getProperty((String)key).replace("/",File.separator));
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            System.out.println("请在程序目录中添加dir.conf文件，文件内容示例：");
            System.out.println("dir1=DCIM/Camera");
            System.out.println("dir2=DCIM/WeiXin");
            System.out.println("dir3=XXXX/XXXX");
            return null;
        }

        return pro;
    }

    private static boolean copyFile(File source,File target,Map<String,String> repeatMap){

        if(target.exists()){
            target=new File(repeatFiles+File.separator+source.getName().substring(0,source.getName().lastIndexOf("."))+(System.currentTimeMillis() % 24*60*60*1000)+source.getName().substring(source.getName().lastIndexOf(".")));
            repeatMap.put(source.getName(),target.getPath());
        }
        if(!target.getParentFile().exists()){
            target.getParentFile().mkdirs();
        }
        try(
                FileChannel input=new FileInputStream(source).getChannel();
                FileChannel ouput=new FileOutputStream(target).getChannel();
        ){
            ouput.transferFrom(input,0,input.size());
            return true;
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    private static void getFileType(){
        File file= new File(rootPath+File.separator+ "type.conf");
        Properties pro=new Properties();
        if(file.exists()) {
            try (FileReader fr = new FileReader(file)) {
                pro.load(fr);
                type_picture=","+pro.getProperty("picture")+",";
                type_video=","+pro.getProperty("video")+",";
                return;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        type_picture=",jpg,";
        type_video=",mp4,";
    }

    private static String getMTPRootPath(){
        if(isWidows){
            return "y:"+File.separator;
        }else {
            //查找用户ID
            String userID = null;
            try (
                    BufferedReader br = new BufferedReader(new FileReader("/etc/passwd"));
            ) {
                String line = null;
                while ((line = br.readLine()) != null) {
                    if (line.startsWith(System.getProperty("user.name") + ":")) {
                        userID = line.split(":")[2];
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }

            if (userID == null) {
                System.out.println("---无法确定当前登录账号！");
                return null;
            }
            String mtpPath = "/run/user/" + userID + "/gvfs/";
            File file = new File(mtpPath);
            if (!file.exists() || file.listFiles() == null) {
                System.out.println("---没有查询到手机MTP目录，退出！");
                return null;
            }
            String rootDir = null;
            if (file.listFiles() != null && file.listFiles().length > 0) {
                for(File temp : file.listFiles()){
                    if (temp.getName().indexOf("share=内部存储")>0) {
                        return mtpPath + temp.getName() + File.separator;
                    }
                }
                for (File temp : file.listFiles()[0].listFiles()) {
                    if (temp.getName().startsWith("内部") || temp.getName().indexOf("share=内部存储")>0) {
                        rootDir = file.listFiles()[0].getName() + File.separator + temp.getName();
                        return mtpPath + rootDir + File.separator;
                    }
                }
            }

            if (rootDir == null) {
                System.out.println("---没有查询到手机MTP目录，退出！");
                return null;
            }
            return mtpPath + rootDir + File.separator;
        }
    }


    private static void count(Map<String,Integer> map , String type){
        Integer num=map.get(type);
        num=num==null?1:num.intValue()+1;
        map.put(type,num);
    }

    private static String getTargetPath(int type,File file) {
        String namePath = getTimeStam(file);
        if(type==1){
            String metaPath = ImageTool.getDate(file);
            String targetPath = namePath;
            if (metaPath == null && namePath == null){
                return null;
            }else if(metaPath!=null && namePath==null) {
                targetPath = metaPath;
            }else if(metaPath==null && namePath!=null){
                targetPath = namePath;
            }else{
                targetPath = metaPath.compareTo(namePath)>0?namePath:metaPath;
            }
            return path_picture+File.separator+targetPath;
        }else{
            return path_video+File.separator+namePath;
        }
    }

    private static String getTimeStam(File file){
        String name=file.getName();
        if(name.startsWith("IMG_")){
            String[] temp=name.split("_");
            return temp[1].substring(0,4)+"-"+temp[1].substring(4,6);
        }else if(name.startsWith("wx_camera_")){
            String temp=name.split("_")[2].split("\\.")[0];
            Calendar cal=Calendar.getInstance();
            cal.setTimeInMillis(Long.parseLong(temp));
            return cal.get(Calendar.YEAR)+"-"+getMonth(cal.get(Calendar.MONTH)+1);
        }else if(name.startsWith("mmexport") && name.length()==25){
            Calendar cal=Calendar.getInstance();
            cal.setTimeInMillis(Long.parseLong(name.substring("mmexport".length(),name.indexOf("."))));
            return cal.get(Calendar.YEAR)+"-"+getMonth(cal.get(Calendar.MONTH)+1);
        }else if(name.startsWith("VID_")){
            String[] temp=name.split("_");
            return temp[1].substring(0,4)+"-"+temp[1].substring(4,6);
        }else if(name.length()==17){
            Calendar cal=Calendar.getInstance();
            cal.setTimeInMillis(Long.parseLong(name.split("\\.")[0]));
            return cal.get(Calendar.YEAR)+"-"+getMonth(cal.get(Calendar.MONTH)+1);
        }
        return null;
    }

    private static String getMonth(int month){
        return month<10?"0"+month:""+month;
    }

    private static int getType(String type){
        if(type_picture.indexOf(","+type+",")>=0){
            return 1;
        }
        if(type_video.indexOf(","+type+",")>=0){
            return 2;
        }
        return 0;
    }
}
